/**
 * 
 */
package neptune.web.client.view.components.editor;

import neptune.web.client.model.topology.SerializableLink;
import neptune.web.client.model.topology.SerializableMACAddress;
import neptune.web.client.model.topology.SerializableNetworkInterface;
import neptune.web.client.model.topology.SerializableNode;
import neptune.web.client.model.topology.SerializableTopology;
import neptune.web.client.utils.TopologyGenerationUtils;
import neptune.web.client.view.input.DefaultInputValidator;
import neptune.web.client.view.input.MACInputValidator;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * @author Roberto Bifulco [RobertoBifulco.it] [info@robertoBifulco.it]
 * 
 */
public class NetIFPropsDialog extends DialogBox {

	private static final String IMG_AUTOGENERATE = "img/GearWheel.png";
	private FlexTable mainPanel;
	private TextBox id;
	private ListBox binding;
	private TextBox mac;
	private ClickListener okListener = new ClickListener() {
		public void onClick(Widget sender) {
			if (validateInputs()) {
				updateReferences(id.getText());
				interf.setInterfaceName(id.getText());
				interf.setBindingDescription(binding.getItemText(binding
						.getSelectedIndex()));
				if (interf.getMacAddress() == null)
					interf.setMacAddress(new SerializableMACAddress());
				interf.getMacAddress().setAddress(mac.getText());

				NetworkIFMenuBar widget = (NetworkIFMenuBar) treeItem
						.getWidget();
				widget.setText(interf.getInterfaceName());
				NetIFPropsDialog.this.hide();
			}
		}

		private void updateReferences(String newId) {
			if (newId.equals(interf.getInterfaceName()))
				return;

			for (SerializableLink link : topology.getLinks()) {

				if (link.getSource() != null) {
					if (node.getId().equals(link.getSource().getNodeId())) {
						if (interf.getInterfaceName().equals(
								link.getSource().getInterfaceId()))
							link.getSource().setInterfaceId(newId);
					}
				}
				if (link.getDestination() != null) {
					if (node.getId().equals(link.getDestination().getNodeId())) {
						if (interf.getInterfaceName().equals(
								link.getDestination().getInterfaceId()))
							link.getDestination().setInterfaceId(newId);
					}
				}
			}
		}
	};
	private ClickListener cancelListener = new ClickListener() {
		public void onClick(Widget sender) {
			if (cancelCallBack != null)
				cancelCallBack.onCancel();
			NetIFPropsDialog.this.hide();
		}
	};
	private SerializableNetworkInterface interf;
	private TreeItem treeItem;
	private CancelCallBack cancelCallBack;
	private Image autoGenerate;
	private final SerializableTopology topology;
	private final SerializableNode node;

	public NetIFPropsDialog(SerializableNetworkInterface interf,
			SerializableNode node, SerializableTopology topology,
			TreeItem treeItem) {
		super(false, true);
		this.node = node;
		this.topology = topology;

		this.treeItem = treeItem;

		mainPanel = new FlexTable();
		mainPanel.setWidth("95%");
		ScrollPanel mainPanelWrapper = new ScrollPanel(mainPanel);
		mainPanelWrapper.setHeight("200px");

		/*
		 * Inizio costruzione campi per inserimemnto dati
		 */
		// ID
		Label idLabel = new Label("Interface name");
		idLabel.setStylePrimaryName("NodePropsDialog-label");
		id = new TextBox();
		id.setStylePrimaryName("NodePropsDialog-input");
		mainPanel.setWidget(0, 0, idLabel);
		mainPanel.setWidget(0, 1, id);

		// BINDING DESCRIPTION
		Label bindingLabel = new Label("Binding");
		bindingLabel.setStylePrimaryName("NodePropsDialog-label");
		binding = new ListBox();
		binding.addStyleName("NodePropsDialog-input");
		binding.addItem(SerializableNetworkInterface.UNDEFINED);
		binding.addItem(SerializableNetworkInterface.BRIDGE);
		binding.addItem(SerializableNetworkInterface.HIF);
		binding.addItem(SerializableNetworkInterface.NAT);
		binding.setSelectedIndex(1);
		mainPanel.setWidget(1, 0, bindingLabel);
		mainPanel.setWidget(1, 1, binding);

		// MAC
		Label macLabel = new Label("MAC address");
		macLabel.addStyleName("NodePropsDialog-label");
		mac = new TextBox();
		mac.addStyleName("NodePropsDialog-input");
		mainPanel.setWidget(2, 0, macLabel);
		mainPanel.setWidget(2, 1, mac);

		FlowPanel autoGenPanel = new FlowPanel();
		autoGenPanel.setWidth("330px");
		HorizontalPanel hPanel = new HorizontalPanel();
		autoGenerate = new Image(IMG_AUTOGENERATE);
		// autoGenerate = new CheckBox("Auto Generate MAC address");
		// autoGenerate.setChecked(true);
		autoGenerate.addClickListener(new ClickListener() {

			public void onClick(Widget sender) {
				if (Window.confirm("The actual interface MAC "
						+ "address will be changed, continue?")) {
					mac.setText(TopologyGenerationUtils.generateRandomMAC());
				}
			}
			// public void onClick(Widget sender) {
			// if (autoGenerate.isChecked()) {
			// mac.setEnabled(false);
			// mac.setText(TopologyGenerationUtils.generateRandomMAC());
			// } else
			// mac.setEnabled(true);
			// }
		});
		hPanel.add(autoGenerate);
		Label autoGenImgLabel = new Label(" Auto Generate MAC address");
		hPanel.add(autoGenImgLabel);
		autoGenPanel.add(hPanel);
		Label autoGenLabel = new Label("Use this option to "
				+ "set a system generated MAC address "
				+ "for this network adapter.");
		autoGenPanel.add(autoGenLabel);
		mainPanel.setWidget(3, 0, autoGenPanel);
		mainPanel.getFlexCellFormatter().setColSpan(3, 0, 2);

		// BUTTON PANEL
		HorizontalPanel buttonPanel = new HorizontalPanel();
		Button ok = new Button("Ok");
		ok.addClickListener(okListener);
		ok.addStyleName("NodePropsDialog-button");
		Button cancel = new Button("Cancel");
		cancel.addClickListener(cancelListener);
		cancel.addStyleName("NodePropsDialog-button");
		buttonPanel.add(ok);
		buttonPanel.add(cancel);

		VerticalPanel vPanel = new VerticalPanel();
		vPanel.setWidth("100%");
		vPanel.add(mainPanelWrapper);
		vPanel.add(buttonPanel);
		vPanel.setCellHorizontalAlignment(buttonPanel,
				VerticalPanel.ALIGN_RIGHT);

		this.setWidget(vPanel);
		this.setText("Network Interface Properties");

		// Styles
		mainPanelWrapper.addStyleName("NodePropsDialog-mainWrapper");
		mainPanel.addStyleName("NodePropsDialog-mainPanel");
		this.addStyleName("NodePropsDialog");
		autoGenPanel.addStyleName("NodePropsDialog-autoGenPanel");
		autoGenerate.addStyleName("NetIFPropsDialog-autoGenImg");
		autoGenImgLabel.addStyleName("NetIFPropsDialog-autoGenImgLabel");

		setData(interf);
	}

	public boolean validateInputs() {
		// Resetta le segnalazioni d'errore
		id.removeStyleName("NodePropsDialog-input-error");
		mac.removeStyleName("NodePropsDialog-input-error");

		DefaultInputValidator defaultValidator = new DefaultInputValidator();
		MACInputValidator macValidator = new MACInputValidator();

		boolean[] correct = new boolean[2];
		for (int i = 0; i < correct.length; i++)
			correct[i] = true;

		if (!defaultValidator.isValid(id.getText())) {
			correct[0] = false;
			id.addStyleName("NodePropsDialog-input-error");
		}
		if (!macValidator.isValid(mac.getText()) && !mac.getText().equals("")) {
			correct[1] = false;
			mac.addStyleName("NodePropsDialog-input-error");
		}

		for (int i = 0; i < correct.length; i++) {
			if (!correct[i])
				return false;
		}

		return true;
	}

	public void setData(SerializableNetworkInterface interf) {
		id.setText(interf.getInterfaceName());
		if (interf.getInterfaceName().equals("eth0"))
			id.setEnabled(false);
		if (interf.getBindingDescription() != null) {
			int itemNumb = binding.getItemCount();
			for (int i = 0; i < itemNumb; i++) {
				if (binding.getItemText(i).equals(
						interf.getBindingDescription())) {
					binding.setSelectedIndex(i);
					break;
				}
			}
		}
		if (interf.getMacAddress() != null) {
			mac.setText(interf.getMacAddress().getAddress());
			mac.setEnabled(true);
			// autoGenerate.setChecked(false);
		}
		if (mac.getText() == null || mac.getText().equals("")) {
			mac.setText(TopologyGenerationUtils.generateRandomMAC());
			// mac.setEnabled(false);
			// autoGenerate.setChecked(true);
		}

		this.interf = interf;
	}

	public void setCancelCallback(CancelCallBack cancelCallBack) {
		this.cancelCallBack = cancelCallBack;
	}

	/**
	 * @return the cancelCallBack
	 */
	public CancelCallBack getCancelCallBack() {
		return cancelCallBack;
	}

}
